<?php
class Tv_Arte_Nav_Factory
{
    /**
     * @staticvar Array of Tv_Arte_Nav_IComponentData
     */
    private static $_dp;
    /**
     * @static
     * @param   Int $idParent
     * @param   String $table
     * @param   Tv_Arte_Nav_ARenderer $renderer
     * @return  String 
     */
    public static function table($idParent, $table, Tv_Arte_Nav_ARenderer $renderer)
    {
        $select = Tv_Arte_Reg::getDb()->select()->from($table)->order('order ASC');
        $dp = $select->query()->fetchAll();
        $tmp = Array();
        foreach ($dp as &$value) { array_push($tmp, new Tv_Arte_Nav_Std_Data($value)); } unset($value);
        $dp = $tmp;
        return self::dp($idParent, $dp, $renderer);
    }
    /**
     * @static
     * @param   Int $idParent
     * @param   Array of Tv_Arte_Nav_IComponentData
     * @param   Tv_Arte_Nav_ARenderer $renderer
     * @return  String 
     */
    public static function dp($idParent, Array $dp, Tv_Arte_Nav_ARenderer $renderer)
    {
        self::$_dp = $dp;
        $composite = new Tv_Arte_Nav_Composite();
        self::_build($idParent, $composite, 0);
        $it = new Tv_Arte_Nav_Iterator($composite->getChildren());
        return Tv_Arte_Nav_ARenderer::render($renderer, $it, 0);
    }
    /**
     * @static
     * @param   Int $parentId 
     * @return  void
     */
    private static function _build($parentId, Tv_Arte_Nav_AComponent &$component, $depth=0)
    {
        foreach (self::$_dp as $key => $value) { /* @var $value Tv_Arte_Nav_Std_Data */
            $data = $value->getData();
            if ($parentId == $value->getParentId()) {
                $newComponent = (self::_hasChildren($value)) ? new Tv_Arte_Nav_Composite() : new Tv_Arte_Nav_Leaf();
                $component->add($newComponent);
                $newComponent->setComponentData($value);
                $value->setDepth($depth + 1); 
                self::_build($value->getId(), $newComponent, $depth + 1);
            }
        }
    }
    /**
     * @static
     * @param   Tv_Arte_Nav_IComponentData $current
     * @return  Boolean 
     */
    private static function _hasChildren($current)
    {
       foreach (self::$_dp as $key => $value) {
           if ($current->getId() == $value->getParentId()) { return true; }
       }
       return false;
    }
}